package yz.cp.back.common.utils;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.google.common.base.CaseFormat;
import com.google.common.collect.Lists;
import com.mzlion.core.lang.StringUtils;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import yz.cp.back.common.vo.PageVo;

import java.util.List;
import java.util.Optional;

public class PageKit {
    public static <T> Page<T> buildPage(Pageable pageable, QueryWrapper<T> wrapper) {
        Page<T> page = new Page<>(pageable.getPageNumber(), pageable.getPageSize());
        Sort sort = pageable.getSort();
        sort.forEach(v -> {
            if (v.getDirection().equals(Sort.Direction.ASC)) {
                wrapper.orderByAsc(CaseFormat.LOWER_CAMEL.to(CaseFormat.LOWER_UNDERSCORE, v.getProperty()));
            } else {
                wrapper.orderByDesc(CaseFormat.LOWER_CAMEL.to(CaseFormat.LOWER_UNDERSCORE, v.getProperty()));
            }
        });
        return page;
    }

    public static Page buildPage(Pageable pageable) {
        Page page = new Page<>(pageable.getPageNumber(), pageable.getPageSize());
        Sort sort = pageable.getSort();
        List<String> asc = Lists.newArrayList();
        List<String> desc = Lists.newArrayList();
        sort.forEach(v -> {
            if (v.getDirection().equals(Sort.Direction.ASC)) {
                asc.add(CaseFormat.LOWER_CAMEL.to(CaseFormat.LOWER_UNDERSCORE, v.getProperty()));
            } else {
                desc.add(CaseFormat.LOWER_CAMEL.to(CaseFormat.LOWER_UNDERSCORE, v.getProperty()));
            }
        });
        page.setAscs(asc);
        page.setDescs(desc);
        return page;
    }
    public static Page buildPage(PageVo pageVo) {
        Page page = new Page(pageVo.getPage(), pageVo.getSize());
        if(pageVo.getSort()!=null&&pageVo.getSort().size()>0){
            Sort sort = parseParameterIntoSort(pageVo.getSort().stream().toArray(String[]::new), ",");
            List<String> asc = Lists.newArrayList();
            List<String> desc = Lists.newArrayList();
            sort.forEach(v -> {
                if (v.getDirection().equals(Sort.Direction.ASC)) {
                    asc.add(CaseFormat.LOWER_CAMEL.to(CaseFormat.LOWER_UNDERSCORE, v.getProperty()));
                } else {
                    desc.add(CaseFormat.LOWER_CAMEL.to(CaseFormat.LOWER_UNDERSCORE, v.getProperty()));
                }
            });
            page.setAscs(asc);
            page.setDescs(desc);
        }

        return page;

    }

    public static <T> Page<T> buildPage(PageVo pageVo, QueryWrapper<T> wrapper) {
        Page<T> page = new Page<>(pageVo.getPage(), pageVo.getSize());
        if(pageVo.getSort()!=null&&pageVo.getSort().size()>0){
            Sort sort = parseParameterIntoSort(pageVo.getSort().stream().toArray(String[]::new), ",");
            sort.forEach(v -> {
                if (v.getDirection().equals(Sort.Direction.ASC)) {
                    wrapper.orderByAsc(CaseFormat.LOWER_CAMEL.to(CaseFormat.LOWER_UNDERSCORE, v.getProperty()));
                } else {
                    wrapper.orderByDesc(CaseFormat.LOWER_CAMEL.to(CaseFormat.LOWER_UNDERSCORE, v.getProperty()));
                }
            });
        }
        return page;
    }

    /**
     *  ctime,rtime,desc,utime,asc
     * @param source
     * @param delimiter
     * @return
     */
    public static Sort parseParameterIntoSort(String[] source, String delimiter) {
        List<Sort.Order> allOrders = Lists.newArrayList();
        String[] var4= source;
        int var5 = source.length;
        List<String> a=Lists.newLinkedList();
        boolean flag=false;
        if(var5>1) {
        for(int i=0;i<var5;++i){
            if(flag){
                flag=false;
                continue;
            }
            if(i+1<var5){
                if("DESC".equalsIgnoreCase(source[i+1])||
                        "ASC".equalsIgnoreCase(source[i+1])){
                    a.add(source[i]+delimiter+source[i+1]);
                    flag=true;
                }else {
                    a.add(source[i]);
                }
            }
        }
            var4=a.toArray(new String[a.size()]);
            var5=var4.length;
        }
        for (int var6 = 0; var6 < var5; ++var6) {
            String part = var4[var6];

            if (part != null) {
                String[] elements = part.split(delimiter);
                Optional<Sort.Direction> direction = elements.length == 0 ? Optional.empty() : Sort.Direction.fromOptionalString(elements[elements.length - 1]);
                int lastIndex = (Integer) direction.map((it) ->
                        elements.length - 1
                ).orElseGet(() ->
                        elements.length
                );

                for (int i = 0; i < lastIndex; ++i) {
                    toOrder(elements[i], direction).ifPresent(allOrders::add);
                }
            }
        }

        return allOrders.isEmpty() ? Sort.unsorted() : Sort.by(allOrders);
    }

    public static Optional<Sort.Order> toOrder(String property, Optional<Sort.Direction> direction) {
        return !StringUtils.hasText(property) ? Optional.empty() : Optional.of(direction.map((it) ->
                new Sort.Order(it, property)
        ).orElseGet(() ->
                Sort.Order.by(property)
        ));
    }
}
